home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / util / max / flyfao / flyfao.cpp next >
Encoding:
C/C++ Source or Header  |  2000-08-08  |  17.0 KB  |  790 lines

  1. #include "Max.h"
  2. #include "resource.h"
  3. #include "istdplug.h"
  4. #include "iparamm.h"
  5. #include "flyfao.h"
  6.  
  7. HINSTANCE hInstance;
  8. int controlsInit = FALSE;
  9.  
  10. TCHAR *GetString(int id);
  11.  
  12. extern HINSTANCE hInstance;
  13.  
  14. IObjParam *Flyfao::ip            = NULL;
  15. IParamMap *Flyfao::pmapParam    = NULL;
  16.  
  17. class FlyfaoClassDesc:public ClassDesc {
  18.     public:
  19.     int             IsPublic() {return 1;}
  20.     void *            Create(BOOL loading = FALSE) {return new Flyfao();}
  21.     const TCHAR *    ClassName() {return GetString(IDS_CLASS_NAME);}
  22.     SClass_ID        SuperClassID() {return GEOMOBJECT_CLASS_ID;}
  23.     Class_ID        ClassID() {return FLYFAO_CLASS_ID;}
  24.     const TCHAR*     Category() {return GetString(IDS_CATEGORY);}
  25.     void            ResetClassParams (BOOL fileReset);
  26. };
  27.  
  28. class flyfaoDlg : public ParamMapUserDlgProc {
  29.     public:
  30.         Flyfao *ff;
  31.         BOOL DlgProc(TimeValue t,IParamMap *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
  32.         void DeleteThis() {}
  33.     };
  34.  
  35. class PickControlNode : 
  36.         public PickModeCallback,
  37.         public PickNodeCallback {
  38.     public:                
  39.         Flyfao *ff;
  40.         INode *node;
  41.  
  42.         PickControlNode() { ff=NULL; node=NULL; }
  43.         BOOL HitTest(IObjParam *ip,HWND hWnd,ViewExp *vpt,IPoint2 m,int flags);        
  44.         BOOL Pick(IObjParam *ip,ViewExp *vpt);        
  45.         void EnterMode(IObjParam *ip);
  46.         void ExitMode(IObjParam *ip);        
  47.         BOOL Filter(INode *node);
  48.         PickNodeCallback *GetFilter() { return this; }
  49.         BOOL RightClick(IObjParam *ip,ViewExp *vpt) { return TRUE; }
  50.     };
  51.  
  52. class FlyfaoCreateCallBack : public CreateMouseCallBack {
  53.     IPoint2 sp0;
  54.     Flyfao *ob;
  55.     Point3 p0;
  56. public:    
  57.     int proc( ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat);
  58.     void SetObj(Flyfao *obj) {ob = obj;}
  59. };
  60.  
  61. static flyfaoDlg flyfaodlg;
  62. static FlyfaoClassDesc FlyfaoDesc;
  63. static PickControlNode thePickMode;
  64. static FlyfaoCreateCallBack FlyfaoCreateCB;
  65.  
  66. ClassDesc* GetFlyfaoDesc() { return &FlyfaoDesc; }
  67.  
  68. #define PB_KEY    0
  69.  
  70. static ParamUIDesc descParam[] = {
  71.     ParamUIDesc(
  72.         PB_KEY,
  73.         EDITTYPE_INT,
  74.         IDC_KEY,IDC_KEY_SPIN,
  75.         0,256,
  76.         1),    
  77.     };     
  78.  
  79. #define PARAMDESC_LENGTH 1
  80.  
  81. static ParamBlockDescID descVer1[] = {
  82.     { TYPE_INT, NULL, TRUE, 0 },
  83.     };
  84.  
  85. #define CURRENT_DESCRIPTOR descVer1
  86.  
  87. #define PBLOCK_LENGTH    1
  88.  
  89. #define CURRENT_VERSION    1
  90.  
  91. BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved)
  92. {
  93.     hInstance = hinstDLL;
  94.  
  95.     if (!controlsInit) {
  96.         controlsInit = TRUE;
  97.         InitCustomControls(hInstance);
  98.         InitCommonControls();
  99.     }
  100.             
  101.     return (TRUE);
  102. }
  103.  
  104. __declspec( dllexport ) const TCHAR* LibDescription()
  105. {
  106.     return GetString(IDS_LIBDESCRIPTION);
  107. }
  108.  
  109. __declspec( dllexport ) int LibNumberClasses()
  110. {
  111.     return 1;
  112. }
  113.  
  114. __declspec( dllexport ) ClassDesc* LibClassDesc(int i)
  115. {
  116.     switch(i) {
  117.         case 0: return GetFlyfaoDesc();
  118.         default: return 0;
  119.     }
  120. }
  121.  
  122. __declspec( dllexport ) ULONG LibVersion()
  123. {
  124.     return VERSION_3DSMAX;
  125. }
  126.  
  127. TCHAR *GetString(int id)
  128. {
  129.     static TCHAR buf[256];
  130.     if (hInstance)
  131.         return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL;
  132.     return NULL;
  133. }
  134.  
  135. void FlyfaoClassDesc::ResetClassParams (BOOL fileReset) 
  136. {
  137. }
  138.  
  139. BOOL PickControlNode::Filter(INode *node)
  140.     {
  141.     node->BeginDependencyTest();
  142.     ff->NotifyDependents(FOREVER,0,REFMSG_TEST_DEPENDENCY);
  143.     if (node->EndDependencyTest()) 
  144.         return FALSE;
  145.     else return TRUE;
  146.     }
  147.  
  148. BOOL PickControlNode::HitTest(
  149.         IObjParam *ip,HWND hWnd,ViewExp *vpt,IPoint2 m,int flags)
  150.     {    
  151.     if (ip->PickNode(hWnd,m,this)) 
  152.         return TRUE;
  153.     else return FALSE;
  154.     }
  155.  
  156. BOOL PickControlNode::Pick(IObjParam *ip,ViewExp *vpt)
  157.     {
  158.     node = vpt->GetClosestHit();
  159.     if (node) 
  160.         {
  161.  
  162.         }
  163.     return TRUE;
  164.     }
  165.  
  166. void PickControlNode::EnterMode(IObjParam *ip)
  167.     {
  168.     node=0;
  169.     }
  170.  
  171. void PickControlNode::ExitMode(IObjParam *ip)
  172.     {
  173.     if (node)
  174.         {
  175.         Object *obj = node->EvalWorldState(ip->GetTime()).obj;
  176.         if(obj->CanConvertToType(triObjectClassID))
  177.             {
  178.             char *name=node->GetName();
  179.             Mesh *mesh=&((TriObject *)obj->ConvertToType(ip->GetTime(),triObjectClassID))->mesh;
  180.             Matrix3 piv(1);
  181.             piv.PreTranslate(node->GetObjOffsetPos());
  182.             PreRotateMatrix(piv, node->GetObjOffsetRot());
  183.             ApplyScaling(piv, node->GetObjOffsetScale());
  184.             Matrix3 tm=node->GetObjectTM(ip->GetTime());
  185.             Point3 pos=tm.GetTrans();
  186.             ff->add_key(mesh,tm,pos,piv);
  187.             }
  188.         }
  189.     }
  190.  
  191. void Flyfao::add_key(Mesh *mesh,Matrix3 tm,Point3 pos, Matrix3 piv)
  192. {
  193.     if (nkeys==0)
  194.         {
  195.         nfaces=mesh->numFaces;
  196.         nverts=mesh->numVerts;
  197.         verts=new float[nverts*3];
  198.         faces=new unsigned short[nfaces*3];
  199.         uvs=new float[nfaces*3*2];
  200.         int i;
  201.         Point3 p;
  202.         for( i=0;i<nverts;i++ )
  203.         {
  204.             p=mesh->verts[i]*piv;
  205.             p=p*tm;
  206.             p=p-pos;
  207.              verts[i*3]=p.x;
  208.             verts[i*3+1]=p.y;
  209.             verts[i*3+2]=p.z;
  210.         }
  211.         for( i=0;i<nfaces;i++ )
  212.             {
  213.             faces[i*3]=(unsigned short)mesh->faces[i].v[0];
  214.             faces[i*3+1]=(unsigned short)mesh->faces[i].v[1];
  215.             faces[i*3+2]=(unsigned short)mesh->faces[i].v[2];
  216.             if (mesh->tVerts)
  217.                 {
  218.                 uvs[i*6]=mesh->tVerts[mesh->tvFace[i].t[0]].x;
  219.                 uvs[i*6+1]=mesh->tVerts[mesh->tvFace[i].t[0]].y;
  220.                 uvs[i*6+2]=mesh->tVerts[mesh->tvFace[i].t[1]].x;
  221.                 uvs[i*6+3]=mesh->tVerts[mesh->tvFace[i].t[1]].y;
  222.                 uvs[i*6+4]=mesh->tVerts[mesh->tvFace[i].t[2]].x;
  223.                 uvs[i*6+5]=mesh->tVerts[mesh->tvFace[i].t[2]].y;
  224.                 }
  225.             else
  226.                 uvs[i*6]=uvs[i*6+1]=uvs[i*6+2]=
  227.                 uvs[i*6+3]=uvs[i*6+4]=uvs[i*6+5]=0;
  228.             }
  229.         nkeys++;
  230.         }
  231.     else if (mesh->numVerts==nverts && mesh->numFaces==nfaces)
  232.     {
  233.         int i,j=nverts*nkeys;
  234.         float *tmp=new float[(j+nverts)*3];
  235.         memcpy(tmp,verts,sizeof(float)*j*3);
  236.         delete verts;
  237.         verts=tmp;
  238.         Point3 p;
  239.         for( i=0;i<nverts;i++ )
  240.         {
  241.             p=mesh->verts[i]*piv;
  242.             p=p*tm;
  243.             p=p-pos;
  244.              verts[(j+i)*3]=p.x;
  245.             verts[(j+i)*3+1]=p.y;
  246.             verts[(j+i)*3+2]=p.z;
  247.         }
  248.         nkeys++;
  249.     }
  250.     char str[256];
  251.     sprintf(str,"Num faces: %i",nfaces);
  252.     SetDlgItemText(hParams,IDC_NUMFACES,str);
  253.     sprintf(str,"Num verts: %i",nverts);
  254.     SetDlgItemText(hParams,IDC_NUMVERTS,str);
  255.     sprintf(str,"Total keys: %i",nkeys);
  256.     SetDlgItemText(hParams,IDC_NUMKEYS,str);
  257.     pblock->SetValue(PB_KEY,0,0);
  258. }
  259.  
  260. Flyfao::Flyfao()
  261. {
  262.     nkeys=0;
  263.     nverts=0;
  264.     nfaces=0;
  265.     verts=0;
  266.     uvs=0;
  267.     faces=0;
  268.  
  269.     pblock = CreateParameterBlock(
  270.                 CURRENT_DESCRIPTOR, 
  271.                 PBLOCK_LENGTH, 
  272.                 CURRENT_VERSION);
  273.     assert(pblock);
  274.     MakeRefByID(FOREVER, 0, pblock);
  275. }
  276.  
  277. Flyfao::~Flyfao()
  278. {
  279.     if (faces) delete faces;
  280.     if (verts) delete verts;
  281.     if (uvs) delete uvs;
  282. }
  283.  
  284. #define FAO_DATA_CHUNK 9100
  285.  
  286. TCHAR *Flyfao::GetObjectName()
  287. {
  288.     return GetString(IDS_CLASS_NAME); 
  289. }
  290.  
  291. IOResult Flyfao::Load(ILoad *iload)
  292. {
  293.     ULONG nb;
  294.     IOResult res;
  295.     while (IO_OK==(res=iload->OpenChunk())) 
  296.     {
  297.         switch(iload->CurChunkID())  
  298.         {
  299.             case FAO_DATA_CHUNK:
  300.                 res=iload->Read(&nkeys,sizeof(int),&nb);
  301.                 res=iload->Read(&nfaces,sizeof(int),&nb);
  302.                 res=iload->Read(&nverts,sizeof(int),&nb);
  303.                 if (nfaces)
  304.                 {
  305.                 verts=new float[nkeys*nverts*3];
  306.                 faces=new unsigned short[nfaces*3];
  307.                 uvs=new float[nfaces*3*2];
  308.                 res=iload->Read(faces,nfaces*3*sizeof(unsigned short),&nb);
  309.                 res=iload->Read(uvs,nfaces*3*2*sizeof(float),&nb);
  310.                 res=iload->Read(verts,nkeys*nverts*3*sizeof(float),&nb);
  311.                 }
  312.                 break;
  313.         }
  314.         iload->CloseChunk();
  315.         if (res!=IO_OK)
  316.             return res;
  317.     }
  318.     return IO_OK;
  319. }
  320.  
  321. IOResult Flyfao::Save(ISave *isave)
  322. {
  323.     ULONG nb;
  324.     isave->BeginChunk(FAO_DATA_CHUNK);
  325.     isave->Write(&nkeys,sizeof(int),&nb);
  326.     isave->Write(&nfaces,sizeof(int),&nb);
  327.     isave->Write(&nverts,sizeof(int),&nb);
  328.     isave->Write(faces,nfaces*3*sizeof(unsigned short),&nb);
  329.     isave->Write(uvs,nfaces*3*2*sizeof(float),&nb);
  330.     isave->Write(verts,nkeys*nverts*3*sizeof(float),&nb);
  331.     isave->EndChunk();
  332.     return IO_OK;
  333. }
  334.  
  335. int Flyfao::load_fao(char *file)
  336. {
  337.     if (faces) delete faces;
  338.     if (verts) delete verts;
  339.     if (uvs) delete uvs;
  340.     nkeys=0;
  341.     nverts=0;
  342.     nfaces=0;
  343.     verts=0;
  344.     uvs=0;
  345.     faces=0;
  346.  
  347.     FILE *fp=fopen(file,"rb");
  348.     if (fp)
  349.         {
  350.         int i,j;
  351.         char skin[64];
  352.         float pivotpos[3];
  353.  
  354.         fread(&i,1,sizeof(int),fp);
  355.         if (i!=9171)
  356.             {
  357.             fclose(fp);
  358.             return 0;
  359.             }
  360.         fread(&nfaces,1,sizeof(int),fp);
  361.         fread(&nverts,1,sizeof(int),fp);
  362.         fread(&nkeys,1,sizeof(int),fp);
  363.         fread(&pivotpos,3,sizeof(float),fp);
  364.         fread(skin,1,64,fp);
  365.  
  366.         verts=new float[nverts*nkeys*3];
  367.         uvs=new float[6*nfaces];
  368.         faces=new unsigned short[3*nfaces];
  369.  
  370.         fread(faces,nfaces,sizeof(unsigned short)*3,fp);
  371.         fread(uvs,nfaces,sizeof(float)*6,fp);
  372.         fread(verts,nverts*nkeys,sizeof(float)*3,fp);
  373.         
  374.         fclose(fp);
  375.         
  376.         float fac=(float)GetMasterScale(UNITS_CENTIMETERS)/10;
  377.         j=nverts*nkeys*3;
  378.         for( i=0;i<j;i++ )
  379.         {
  380.             verts[i]/=fac;
  381.         }
  382.  
  383.         return 1;
  384.         }
  385.     return 0;
  386. }
  387.  
  388. int Flyfao::save_fao(char *file,char *skin,Point3 pivot)
  389. {
  390.     FILE *fp=fopen(file,"wb");
  391.     if (fp)
  392.         {
  393.         int i=9171,j;
  394.         char skinfile[64];
  395.         float fac=(float)GetMasterScale(UNITS_CENTIMETERS)/10,f;
  396.         pivot*=fac;
  397.         strncpy(skinfile,skin,63); skin[63]=0;
  398.  
  399.         fwrite(&i,1,sizeof(int),fp);
  400.         fwrite(&nfaces,1,sizeof(int),fp);
  401.         fwrite(&nverts,1,sizeof(int),fp);
  402.         fwrite(&nkeys,1,sizeof(int),fp);
  403.         fwrite(&pivot.x,3,sizeof(float),fp);
  404.         fwrite(skinfile,1,64,fp);
  405.  
  406.         fwrite(faces,nfaces,sizeof(unsigned short)*3,fp);
  407.         fwrite(uvs,nfaces,sizeof(float)*6,fp);
  408.  
  409.         j=nverts*nkeys*3;
  410.         for( i=0;i<j;i++ )
  411.         {
  412.             f=verts[i]*fac;
  413.             fwrite(&f,1,sizeof(float),fp);
  414.         }
  415.         
  416.         j=0;
  417.         fwrite(&j,1,sizeof(int),fp);
  418.  
  419.         fclose(fp);
  420.  
  421.         return 1;
  422.         }
  423.     return 0;
  424. }
  425.  
  426. void Flyfao::delete_key(int key)
  427. {
  428.     if (nkeys>0 && key<nkeys && key>=0)
  429.     if (IDYES==MessageBox(hParams,"Are you sure do delete the curent selected key ?","Fly3D fao object",MB_ICONQUESTION|MB_YESNO))
  430.     {
  431.         if (nkeys==1)
  432.         {
  433.             if (faces) delete faces;
  434.             if (verts) delete verts;
  435.             if (uvs) delete uvs;
  436.             nkeys=0;
  437.             nverts=0;
  438.             nfaces=0;
  439.             verts=0;
  440.             uvs=0;
  441.             faces=0;
  442.             key=0;
  443.         }
  444.         else
  445.         {
  446.             float *tmp=new float[(nkeys-1)*nverts*3];
  447.             memcpy(tmp,verts,sizeof(float)*3*key*nverts);
  448.             memcpy(&tmp[3*key*nverts],&verts[3*nverts*(key+1)],sizeof(float)*3*nverts*(nkeys-key-1));
  449.  
  450.             delete verts;
  451.             verts=tmp;
  452.  
  453.             nkeys--;
  454.             if (key>=nkeys)
  455.                 key=nkeys-1;
  456.             if (key<0) 
  457.                 key=0;
  458.         }
  459.  
  460.         pblock->SetValue(PB_KEY,0,key);
  461.         char str[256];
  462.         sprintf(str,"Num faces: %i",nfaces);
  463.         SetDlgItemText(hParams,IDC_NUMFACES,str);
  464.         sprintf(str,"Num verts: %i",nverts);
  465.         SetDlgItemText(hParams,IDC_NUMVERTS,str);
  466.         sprintf(str,"Total keys: %i",nkeys);
  467.         SetDlgItemText(hParams,IDC_NUMKEYS,str);
  468.     }
  469. }
  470.  
  471. void Flyfao::open_file_dialog()
  472. {
  473.     OPENFILENAME ofn;
  474.     char filename[256]="";
  475.     memset(&ofn,0,sizeof(OPENFILENAME));
  476.     ofn.lStructSize=sizeof(OPENFILENAME);
  477.     ofn.hwndOwner=hParams;
  478.     ofn.hInstance=hInstance;
  479.     ofn.lpstrFilter="Fly animated object (*.fao)\0*.fao\0";
  480.     ofn.lpstrDefExt="fao";
  481.     ofn.lpstrFile=filename;
  482.     ofn.nMaxFile=255;
  483.     ofn.lpstrTitle="Open object";
  484.     ofn.Flags=OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
  485.     if (GetOpenFileName(&ofn))
  486.     {
  487.         load_fao(filename);
  488.  
  489.         pblock->SetValue(PB_KEY,0,0);
  490.         char str[256];
  491.         sprintf(str,"Num faces: %i",nfaces);
  492.         SetDlgItemText(hParams,IDC_NUMFACES,str);
  493.         sprintf(str,"Num verts: %i",nverts);
  494.         SetDlgItemText(hParams,IDC_NUMVERTS,str);
  495.         sprintf(str,"Total keys: %i",nkeys);
  496.         SetDlgItemText(hParams,IDC_NUMKEYS,str);
  497.     }
  498. }
  499.  
  500. void Flyfao::open_save_file_dialog()
  501. {
  502.     OPENFILENAME ofn;
  503.     char filename[256]="";
  504.     memset(&ofn,0,sizeof(OPENFILENAME));
  505.     ofn.lStructSize=sizeof(OPENFILENAME);
  506.     ofn.hwndOwner=hParams;
  507.     ofn.hInstance=hInstance;
  508.     ofn.lpstrFilter="Fly animated object (*.fao)\0*.fao\0";
  509.     ofn.lpstrDefExt="fao";
  510.     ofn.lpstrFile=filename;
  511.     ofn.nMaxFile=255;
  512.     ofn.lpstrTitle="Open object";
  513.     ofn.Flags=OFN_PATHMUSTEXIST;
  514.     if (GetOpenFileName(&ofn))
  515.         save_fao(filename,"",Point3(0,0,0));
  516. }
  517.  
  518. BOOL flyfaoDlg::DlgProc(
  519.         TimeValue t,IParamMap *map,
  520.         HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
  521. {
  522.     switch(msg)
  523.     {
  524.     case WM_INITDIALOG:
  525.         {
  526.         char str[256];
  527.         ff->hParams=hWnd;
  528.         sprintf(str,"Num faces: %i",ff->nfaces);
  529.         SetDlgItemText(hWnd,IDC_NUMFACES,str);
  530.         sprintf(str,"Num verts: %i",ff->nverts);
  531.         SetDlgItemText(hWnd,IDC_NUMVERTS,str);
  532.         sprintf(str,"Total keys: %i",ff->nkeys);
  533.         SetDlgItemText(hWnd,IDC_NUMKEYS,str);
  534.         }
  535.         break;
  536.     case WM_COMMAND:
  537.         switch(wParam)
  538.         {
  539.         case IDC_ADDKEY:
  540.             thePickMode.ff  = ff;
  541.             ff->ip->SetPickMode(&thePickMode);
  542.             break;
  543.         case IDC_DELETEKEY:
  544.             {
  545.             int key;
  546.             ff->pblock->GetValue(PB_KEY,ff->ip->GetTime(),key,FOREVER);
  547.             ff->delete_key(key);
  548.             }
  549.             break;
  550.         case IDC_LOAD:
  551.             ff->open_file_dialog();
  552.             break;
  553.         case IDC_SAVE:
  554.             ff->open_save_file_dialog();
  555.             break;
  556.         }
  557.         break;
  558.     }
  559.     return FALSE;
  560. }
  561.  
  562. void Flyfao::BeginEditParams(IObjParam *ip,ULONG flags,Animatable *prev)
  563. {
  564.     this->ip = ip;
  565.     flyfaodlg.ff=this;
  566.     SimpleObject::BeginEditParams(ip,flags,prev);
  567.  
  568.     if(pmapParam) {
  569.         pmapParam->SetParamBlock(pblock);
  570.     } else {
  571.         pmapParam = CreateCPParamMap(
  572.             descParam, PARAMDESC_LENGTH,
  573.             pblock, 
  574.             ip, 
  575.             hInstance, 
  576.             MAKEINTRESOURCE(IDD_PANEL),
  577.             GetString(IDS_PARAMS), 
  578.             0);
  579.     }
  580.     pmapParam->SetUserDlgProc(&flyfaodlg);
  581. }
  582.  
  583. void Flyfao::EndEditParams( IObjParam *ip, ULONG flags,Animatable *next )
  584. {
  585.     SimpleObject::EndEditParams(ip,flags,next);
  586.     if (flags&END_EDIT_REMOVEUI ) {
  587.         DestroyCPParamMap(pmapParam);
  588.         pmapParam  = NULL;
  589.     }
  590.     this->ip = NULL;
  591. }
  592.  
  593. BOOL Flyfao::HasUVW() 
  594.     return TRUE; 
  595. }
  596.  
  597. void Flyfao::SetGenUVW(BOOL sw) 
  598. {  
  599.     if (sw==HasUVW()) return;
  600. }
  601.  
  602. int FlyfaoCreateCallBack::proc(ViewExp *vpt,int msg, int point, int flags, IPoint2 m, Matrix3& mat )
  603. {
  604.     switch(msg)
  605.     {
  606.     case MOUSE_POINT:
  607.     case MOUSE_MOVE:
  608.         switch(point) 
  609.         {
  610.         case 0: 
  611.             ob->suspendSnap = TRUE;
  612.             sp0 = m;
  613.             p0 = vpt->SnapPoint(m,m,NULL,SNAP_IN_PLANE);
  614.             mat.SetTrans(p0);
  615.             break;
  616.         case 1:
  617.             return CREATE_STOP;
  618.         }
  619.         break;
  620.     case MOUSE_ABORT:
  621.         return CREATE_ABORT;
  622.     }
  623.  
  624.     return TRUE;
  625. }
  626.  
  627. CreateMouseCallBack* Flyfao::GetCreateMouseCallBack() 
  628. {
  629.     FlyfaoCreateCB.SetObj(this);
  630.     return(&FlyfaoCreateCB);
  631. }
  632.  
  633. void Flyfao::BuildMesh(TimeValue t)
  634. {
  635.     int key;
  636.     ivalid = FOREVER;
  637.     pblock->GetValue(PB_KEY,t,key,FOREVER);
  638.     if (key<0)
  639.     {
  640.         pblock->SetValue(PB_KEY,0,0);
  641.         return;
  642.     }
  643.     if (key>=nkeys)
  644.     {
  645.         pblock->SetValue(PB_KEY,0,nkeys-1);
  646.         return;
  647.     }
  648.     if (nkeys==0)
  649.     {
  650.         mesh.setNumVerts(0);
  651.         mesh.setNumFaces(0);
  652.         mesh.setNumTVerts(0);
  653.         mesh.setNumTVFaces(0);
  654.         return;
  655.     }
  656.     mesh.setNumVerts(nverts);
  657.     mesh.setNumFaces(nfaces);
  658.     mesh.setNumTVerts(nfaces*3);
  659.     mesh.setNumTVFaces(nfaces);
  660.     int i,j=nverts*key;
  661.     for( i=0;i<nverts;i++ )
  662.         mesh.setVert(i,verts[(j+i)*3],verts[(j+i)*3+1],verts[(j+i)*3+2]);
  663.     for( i=0;i<nfaces;i++ )
  664.     {
  665.         mesh.faces[i].v[0]=faces[i*3];
  666.         mesh.faces[i].v[1]=faces[i*3+1];
  667.         mesh.faces[i].v[2]=faces[i*3+2];
  668.         mesh.faces[i].flags=EDGE_ALL;
  669.         mesh.faces[i].smGroup=1;
  670.     }
  671.     for( i=0;i<nfaces;i++ )
  672.     {
  673.         mesh.tvFace[i].t[0]=i*3;
  674.         mesh.tvFace[i].t[1]=i*3+1;
  675.         mesh.tvFace[i].t[2]=i*3+2;
  676.         mesh.tVerts[i*3].x=uvs[i*6];
  677.         mesh.tVerts[i*3].y=1.0f-uvs[i*6+1];
  678.         mesh.tVerts[i*3].z=0;
  679.         mesh.tVerts[i*3+1].x=uvs[i*6+2];
  680.         mesh.tVerts[i*3+1].y=1.0f-uvs[i*6+3];
  681.         mesh.tVerts[i*3+1].z=0;
  682.         mesh.tVerts[i*3+2].x=uvs[i*6+4];
  683.         mesh.tVerts[i*3+2].y=1.0f-uvs[i*6+5];
  684.         mesh.tVerts[i*3+2].z=0;
  685.     }
  686.     mesh.InvalidateGeomCache();
  687.     mesh.InvalidateTopologyCache();
  688.     mesh.BuildStripsAndEdges();
  689. }
  690.  
  691. BOOL Flyfao::OKtoDisplay(TimeValue t) 
  692. {
  693.     return TRUE;
  694. }
  695.  
  696. void Flyfao::InvalidateUI() 
  697. {
  698.     if (pmapParam) pmapParam->Invalidate();
  699. }
  700.  
  701. ParamDimension *Flyfao::GetParameterDim(int pbIndex) 
  702. {
  703.     return defaultDim;
  704. }
  705.  
  706. TSTR Flyfao::GetParameterName(int pbIndex) 
  707. {
  708.     return GetString(IDS_PARAMS);
  709. }
  710.  
  711. BOOL Flyfao::SetValue(int i, TimeValue t, int v) 
  712. {
  713.     return TRUE;
  714. }
  715.  
  716. BOOL Flyfao::SetValue(int i, TimeValue t, float v)
  717. {
  718.     return TRUE;
  719. }
  720.  
  721. BOOL Flyfao::SetValue(int i, TimeValue t, Point3 &v) 
  722. {
  723.     return TRUE;
  724. }
  725.  
  726. BOOL Flyfao::GetValue(int i, TimeValue t, int &v, Interval &ivalid) 
  727. {
  728.     return TRUE;
  729. }
  730.  
  731. BOOL Flyfao::GetValue(int i, TimeValue t, float &v, Interval &ivalid) 
  732. {
  733.     return TRUE;
  734. }
  735.  
  736. BOOL Flyfao::GetValue(int i, TimeValue t, Point3 &v, Interval &ivalid) 
  737. {    
  738.     return TRUE;
  739. }
  740.  
  741. Object* Flyfao::ConvertToType(TimeValue t, Class_ID obtype)
  742. {
  743.     return SimpleObject::ConvertToType(t,obtype);
  744. }
  745.  
  746. int Flyfao::CanConvertToType(Class_ID obtype)
  747. {
  748.     if (obtype==defObjectClassID ||
  749.         obtype==triObjectClassID ||
  750.         obtype==FLYFAO_CLASS_ID) {
  751.         return 1;
  752.     } else {        
  753.     return SimpleObject::CanConvertToType(obtype);
  754.         }
  755. }
  756.  
  757. int Flyfao::IntersectRay(
  758.         TimeValue t, Ray& ray, float& at, Point3& norm)
  759. {
  760.     return FALSE;
  761. }
  762.  
  763. void Flyfao::GetCollapseTypes(Tab<Class_ID> &clist,Tab<TSTR*> &nlist)
  764. {
  765.     Object::GetCollapseTypes(clist, nlist);
  766. }
  767.  
  768. RefTargetHandle Flyfao::Clone(RemapDir& remap) 
  769. {
  770.     Flyfao* newob = new Flyfao();    
  771.     if (nkeys)
  772.     {
  773.         newob->nkeys=nkeys;
  774.         newob->nverts=nverts;
  775.         newob->nfaces=nfaces;
  776.  
  777.         newob->faces=new unsigned short[nfaces*3];
  778.         newob->uvs=new float[nfaces*6];
  779.         newob->verts=new float[nkeys*nverts*3];
  780.  
  781.         memcpy(newob->faces,faces,sizeof(unsigned short)*3*nfaces);
  782.         memcpy(newob->uvs,uvs,sizeof(float)*6*nfaces);
  783.         memcpy(newob->verts,verts,sizeof(float)*3*nverts*nkeys);
  784.     }
  785.     newob->ReplaceReference(0,pblock->Clone(remap));
  786.     newob->ivalid.SetEmpty();
  787.     return(newob);
  788. }
  789.